package com.fdb.efp.nls.service.impl.yed.apply;

import com.alibaba.fastjson.JSONObject;
import com.fdb.efp.nls.service.facade.NlsApplyInfoService;
import com.fdb.efp.nls.service.facade.NlsStageInfoService;
import com.fdb.efp.nls.service.facade.UpdateLmtPrdContService;
import com.fdb.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.fdb.efp.nls.service.vo.NlsApplyInfoVO;
import com.fdb.efp.nls.service.vo.NlsStageInfoVO;
import com.fdb.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.fdb.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.fdb.efp.nls.service.vo.yed.AccLoanRespVO;
import com.fdb.efp.nls.service.vo.yed.LoanRepayPlanRespVO;
import com.fdb.efp.nls.service.vo.yed.NlsApplyInfoRespVO;
import com.fdb.basic.framework.core.constant.BaseConstant;
import com.fdb.basic.framework.core.constant.DateFormatConstant;
import com.fdb.basic.framework.core.exception.BizException;
import com.fdb.basic.framework.core.exception.ExternalSysException;
import com.fdb.basic.framework.core.exception.OcmSystemException;
import com.fdb.basic.framework.core.threadpool.ApplicationThreadPool2;
import com.fdb.basic.framework.core.util.*;
import com.fdb.efp.nls.common.ConsoleConstant;
import com.fdb.efp.nls.service.facade.PrdInfoService;
import com.fdb.efp.nls.service.facade.PubSysInfoService;
import com.fdb.efp.nls.service.vo.PrdInfoVO;
import com.fdb.efp.nls.service.facade.CtrLoanContService;
import com.fdb.efp.nls.service.vo.CtrLoanContVO;
import com.fdb.efp.cus.service.facade.CusReferrerInfoService;
import com.fdb.efp.cus.service.vo.CusReferrerInfoVO;
import com.fdb.efp.cus.service.vo.KafkaNoticeHeader;
import com.fdb.efp.esb.service.bo.req.hj.ReqLoanBalanceBean;
import com.fdb.efp.esb.service.bo.req.hj.ReqLoanInfoQueryBean;
import com.fdb.efp.esb.service.bo.req.hj.ReqRepaymentDetailsInfoQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.AcctDtlInfBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespLoanBalanceQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespLoanInfoQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespRepaymentPlanListQueryBean;
import com.fdb.efp.esb.service.facade.hj.LoanInfoQueryService;
import com.fdb.efp.limit.service.facade.LmtPrdContService;
import com.fdb.efp.limit.service.vo.LmtPrdContVO;
import com.fdb.efp.nls.common.LoanConstant;
import com.fdb.efp.nls.service.facade.AccLoanService;
import com.fdb.efp.nls.service.facade.LoanRepayDetailService;
import com.fdb.efp.nls.service.facade.LoanRepayPlanService;
import com.fdb.efp.nls.service.vo.AccLoanVO;
import com.fdb.efp.loan.service.vo.LoanRepayPlanVO;
import com.fdb.efp.nls.common.constant.sed.SedNlsEnum;
import com.fdb.efp.nls.common.util.KafkaUtil;
import com.fdb.efp.nls.service.impl.SoltServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

import static com.fdb.basic.framework.core.constant.BaseConstant.IR_MODE_FIXED;
import static com.fdb.basic.framework.core.constant.BaseConstant.NLS_APPLY_STATE_02;
import static com.fdb.efp.nls.common.constant.yed.YedCommonConstant.FLOW_STATUS_9;

/**
 * 需求编号：优e贷需求编号<br/>
 * 问题编号：<br/>
 * 功能描述：优e贷用信借据、还款计划、还款明细同步插槽<br/>
 * 开发人员：周才顺<br/>
 * 创建时间：2019/8/30 9:42
 *
 * @Author zhoucs1
 * @Version 1.0
 * @Since 1.0
 */
@Service("yedSyncLoanInfoService")
public class YedSyncLoanInfoServiceImpl extends SoltServiceImpl {
    private final Logger logger = LoggerFactory.getLogger(YedSyncLoanInfoServiceImpl.class);
    private final String msgTemplate = "message{}";
    private String msg = "";
//    private String applySeq = "";

    @Autowired
    @Qualifier("loanInfoQueryService")
    LoanInfoQueryService loanInfoQueryService;

    @Autowired
    @Qualifier("accLoanService")
    AccLoanService accLoanService;

    @Autowired
    @Qualifier("accLoanRepayPlanService")
    LoanRepayPlanService loanRepayPlanService;

    @Autowired
    @Qualifier("ctrLoanContService")
    private CtrLoanContService ctrLoanContService;

    @Autowired
    @Qualifier("prdInfoService")
    private PrdInfoService prdInfoService;

    @Autowired
    @Qualifier("lmtPrdContService")
    private LmtPrdContService lmtPrdContService;

    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;

    @Autowired
    @Qualifier("applicationThreadPool")
    private ApplicationThreadPool2 threadPool;

    @Autowired
    @Qualifier("loanRepayDetailService")
    private LoanRepayDetailService repayDetailService;

    @Autowired
    @Qualifier("nlsStageInfoService")
    private NlsStageInfoService nlsStageInfoService;
    @Autowired
    private CusReferrerInfoService cusReferrerInfoService;


    /// kafka主机IP地址
    @Value("${risk.kafkaServers}")
    private String kafkaServers;

    // kafka发送的主题topic
    @Value("${risk.kafkaToptic}")
    private String kafkaToptic;

    @Override
    public void doExecute(NlsProcessBizVO nlsProcessBizVo, NlsApplyInfoVO nlsApplyInfoVO) throws Exception {
        // 流水号
        String applySeq = nlsApplyInfoVO.getApplySeq();
        // 异常位置标识
        String exceptionFlag = nlsApplyInfoVO.getExceptionLocation();
        // 授信申请流水号

        String lmtApplySeq = nlsApplyInfoVO.getLmtApplySeq();
        logger.info("======>借据还款计划同步服务【用信阶段】开始,流水号为:" + applySeq + "<======");

            Objects.requireNonNull(nlsApplyInfoVO);
            Objects.requireNonNull(nlsProcessBizVo);
            logger.info("======>判断网贷过程信息，还款计划信息同步插槽 授信协议信息<======" + nlsApplyInfoVO.toString());
            String loanSeq = nlsApplyInfoVO.getLoanNo();
            String distrNo = nlsApplyInfoVO.getDistrNo();
            if (StringUtils.isEmpty(loanSeq) || StringUtils.isEmpty(distrNo)) {
                if (logger.isErrorEnabled()) {
                    logger.error("优e贷 用信申请流水号【" + applySeq + "】获取贷款号或发放号为空!!!");
                }
                throw new BizException("优e贷 用信申请流水号【" + applySeq + "】获取贷款号或发放号为空!!!");
            }
            ReqLoanInfoQueryBean reqLoanInfoQueryBean = new ReqLoanInfoQueryBean();
            reqLoanInfoQueryBean.setLoanNo(loanSeq);
            reqLoanInfoQueryBean.setDistrNo(distrNo);
            ReqLoanBalanceBean reqLoanBalanceBean = new ReqLoanBalanceBean();
            reqLoanBalanceBean.setLoanNo(loanSeq);
            reqLoanBalanceBean.setDistrNo(distrNo);
            ReqRepaymentDetailsInfoQueryBean reqRepaymentDetailsInfoQueryBean = new ReqRepaymentDetailsInfoQueryBean();
            reqRepaymentDetailsInfoQueryBean.setAcctNo(loanSeq);
            reqRepaymentDetailsInfoQueryBean.setDistrNo(distrNo);
            logger.info("======>还款计划信息同步插槽，接口请求信息<======loanSeq=" + loanSeq + "，distrNo=" + distrNo, msgTemplate);
            // 合同信息
            CtrLoanContVO ctrLoanContVO = new CtrLoanContVO();
            ctrLoanContVO.setSerno(applySeq);
            ctrLoanContVO.setContType(ConsoleConstant.CONT_TYPE_02);
            logger.info("======>还款计划信息同步插槽，合同serno" + lmtApplySeq, msgTemplate);
            CtrLoanContVO queryctrLoanContVO = ctrLoanContService.qryBySernoAndContTyp(ctrLoanContVO);
            if (queryctrLoanContVO == null) {
                msg = "根据授信申请流水号" + applySeq + "和贷款合同类型，网贷未查询到合同数据信息！";
                throw new OcmSystemException(SedNlsEnum.ExceptionLocation.LOAN_RELEASE_SUCCESS_AFTER.getValue(), msg);
            }
            // 产品信息
            PrdInfoVO inPrdInfoVo = new PrdInfoVO();
            // prd_code 产品编号
            inPrdInfoVo.setPrdCode(nlsApplyInfoVO.getPrdCode());
            PrdInfoVO prodVo = prdInfoService.queryByPrdCode(inPrdInfoVo);
            if (prodVo == null) {
                msg = "用信流水号" + applySeq + "网贷未查询到产品数据信息！";
                throw new OcmSystemException(SedNlsEnum.ExceptionLocation.LOAN_RELEASE_SUCCESS_AFTER.getValue(), msg);
            }
            // 查询授信协议
            LmtPrdContVO lmtPrdContVo = lmtPrdContService.qryLmtPrdContByLmtApplySeq(lmtApplySeq);

            // 查询授信信息
            NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
            nlsCreditInfoVO.setLmtApplySeq(lmtApplySeq);
            nlsCreditInfoVO = nlsCreditInfoService.queryByPk(nlsCreditInfoVO);

            RespLoanInfoQueryBean respLoanInfo = new RespLoanInfoQueryBean();
            RespRepaymentPlanListQueryBean respRepaymentPlanListQueryBean = new RespRepaymentPlanListQueryBean();
            RespLoanBalanceQueryBean respLoanBalanceQueryBean = new RespLoanBalanceQueryBean();
            String seq = Integer.toString((int)((Math.random()*9+1)*100000));
            String globalSerno = "108190"+ DateTool.getCurrentDateTimeSSS() + seq;
            logger.info("借据信息查询、还款计划明细查询查询、贷款余额查询流水：【" + globalSerno +"】");
            try {
                // 互金 借据信息查询
                respLoanInfo = loanInfoQueryService.loanInfoQuery(reqLoanInfoQueryBean,globalSerno);
                logger.info("======>还款计划信息同步插槽，借据信息查询 查询 查询返回信息<======" + respLoanInfo.toString());
                // 互金 还款计划明细查询查询
                respRepaymentPlanListQueryBean = loanInfoQueryService.repaymentPlanListQuery(reqRepaymentDetailsInfoQueryBean, globalSerno);
                logger.info("======>还款计划信息同步插槽，还款计划明细查询 查询 查询返回信息<======" + respRepaymentPlanListQueryBean.toString());
                // 互金 贷款余额查询
                respLoanBalanceQueryBean = loanInfoQueryService.loanBalanceQuery(reqLoanBalanceBean, globalSerno);
                logger.info("======>还款计划信息同步插槽，贷款余额  查询 查询返回信息<======" + respLoanBalanceQueryBean.toString());
            } catch (Exception e) {
                throw new ExternalSysException(SedNlsEnum.ExceptionLocation.LOAN_RELEASE_SUCCESS_AFTER.getValue(), "放款成功后，同步借据、还款计划，调用互金接口异常，异常信息为：" + e.getMessage());
            }

            mutatorAccLoan(nlsApplyInfoVO, respLoanInfo, queryctrLoanContVO, prodVo, respLoanBalanceQueryBean, lmtPrdContVo, nlsCreditInfoVO);

            mutatorLoanRepayPlan(respRepaymentPlanListQueryBean, prodVo);
            NlsApplyInfoRespVO respVO = new NlsApplyInfoRespVO();
            respVO.setAmountOfLoan(nlsApplyInfoVO.getAmountOfLoan());
            respVO.setApplySeq(nlsApplyInfoVO.getApplySeq());
            respVO.setCreateTime(nlsApplyInfoVO.getCreateTime());
            respVO.setDnSts(nlsApplyInfoVO.getDnSts());
            respVO.setLastModifyTime(nlsApplyInfoVO.getLastModifyTime());
            respVO.setLmtApplySeq(nlsApplyInfoVO.getLmtApplySeq());
            respVO.setLoanPurpose(nlsApplyInfoVO.getLoanPurpose());
            respVO.setLoanRate(nlsApplyInfoVO.getLoanRate().toString());
            respVO.setLoanTerm(nlsApplyInfoVO.getLoanTerm());
            respVO.setNlsApplyState(nlsApplyInfoVO.getNlsApplyState());
            respVO.setRefuseCause(nlsApplyInfoVO.getRefuseCause());
            respVO.setTableName("NLS_APPLY_INFO");



        // 额度占用
            updateLmtPrdContService.updateLmtProdAfterLoanRelease(nlsApplyInfoVO.getLmtApplySeq(), nlsApplyInfoVO.getApplySeq());
            // 更新用信审批状态为通过状态
            nlsApplyInfoVO.setNlsApplyState(NLS_APPLY_STATE_02);
            nlsApplyInfoVO.setFlowStatus(FLOW_STATUS_9);
            nlsApplyInfoVO.setRefuseCause("");//清空拒绝原因
            logger.info("借据还款计划同步"+JSONObject.toJSONString(nlsApplyInfoVO));
            nlsApplyInfoService.updateByPk(nlsApplyInfoVO);
            logger.info("======>借据还款计划同步服务【用信阶段】结束,流水号为:" + applySeq + "<======");

            sendToRisk(respVO,nlsApplyInfoVO.getApplySeq());

    }

    // 借据信息实时同步
    private void mutatorAccLoan(NlsApplyInfoVO nlsApplyInfoVo, RespLoanInfoQueryBean respLoanInfoQueryBean, CtrLoanContVO queryctrLoanContVO, PrdInfoVO prodVo,
                                RespLoanBalanceQueryBean respLoanBalanceQueryBean, LmtPrdContVO lmtPrdContVo, NlsCreditInfoVO nlsCreditInfoVO) throws Exception {
        AccLoanVO selectAccLoan = new AccLoanVO();
        selectAccLoan.setBillNo(respLoanInfoQueryBean.getAcctKwd());
        selectAccLoan = accLoanService.queryByPk(selectAccLoan);

        CusReferrerInfoVO cusReferrerInfoVO = new CusReferrerInfoVO();
        cusReferrerInfoVO.setLmtApplySeq(nlsCreditInfoVO.getLmtApplySeq());
        cusReferrerInfoVO = cusReferrerInfoService.queryChargeoffBrIdByPk(cusReferrerInfoVO);

        // 异常重试情况,有就跳过，否则主键冲突
        if (Objects.nonNull(selectAccLoan)) return;
        try {
            AccLoanVO accLoanVO = new AccLoanVO();
            // 主键： 用信申请流水号
            accLoanVO.setApplySeq(nlsApplyInfoVo.getApplySeq());
            // 贷款号
            accLoanVO.setLoanSeq(nlsApplyInfoVo.getLoanNo());
            // 发放号
            accLoanVO.setDistrNo(nlsApplyInfoVo.getDistrNo());
            // 借据号
            accLoanVO.setBillNo(respLoanInfoQueryBean.getAcctKwd());
            // 合同号
            if (StringUtil.isStrNotEmpty(queryctrLoanContVO.getContNo())) {
                accLoanVO.setContNo(queryctrLoanContVO.getContNo());
            } else {
                logger.info("cont_no在efp_ctr.ctr_loan_cont表里不存在数据！");
                msg = "cont_no在efp_ctr.ctr_loan_cont表里不存在数据！";
            }
            // 还款频率
            accLoanVO.setRepayFreq(nlsApplyInfoVo.getRepaymentPeriod());
            // 还款周期单位
            accLoanVO.setRepayFreqUnit(nlsApplyInfoVo.getRepaymentPeriodType());
            // 产品主键
            accLoanVO.setPrdId(nlsApplyInfoVo.getPrdId());
            // 产品编号
            accLoanVO.setPrdCode(nlsApplyInfoVo.getPrdCode());
            // 产品名称
            accLoanVO.setPrdName(nlsApplyInfoVo.getPrdName());
            // 客户编号
            accLoanVO.setCusId(nlsApplyInfoVo.getCusId());
            // 客户名称
            accLoanVO.setCusName(nlsApplyInfoVo.getCusName());
            // 币种
            accLoanVO.setCurType(nlsApplyInfoVo.getLoanCcy());
            // 借据金额ContrOriglAmt 合同金额
            accLoanVO.setLoanAmount(StringUtil.isNullorBank(respLoanInfoQueryBean.getContrOriglAmt()) ? BigDecimal.ZERO : new BigDecimal(respLoanInfoQueryBean.getContrOriglAmt()));
            // 借据余额 = 用信放款金额 贷款余额
            accLoanVO.setLoanBalance(Objects.isNull(respLoanBalanceQueryBean.getLoanBal()) ? BigDecimal.ZERO : respLoanBalanceQueryBean.getLoanBal());
            // 起始日 合同开始日期
            accLoanVO.setLoanStartDate(DateUtility.format8To10(respLoanBalanceQueryBean.getContrBegDt()));
            // 到期日 合同结束日期
            accLoanVO.setLoanEndDate(DateUtility.format8To10(respLoanBalanceQueryBean.getContrEndDt()));
            // 原到期日期 合同结束日期
            accLoanVO.setOrigExpiDate(DateUtility.format8To10(respLoanBalanceQueryBean.getContrEndDt()));
            // 利息基准利率 基准利率
            accLoanVO.setRulingIr(StringUtil.isNullorBank(respLoanInfoQueryBean.getBnchmrkRate()) ? BigDecimal.ZERO : new BigDecimal(respLoanInfoQueryBean.getBnchmrkRate()).divide(new BigDecimal("100")));
            // 利息执行年利率 正常利率
            accLoanVO.setRealityIrY(Objects.isNull(respLoanInfoQueryBean.getComIntRate()) ? BigDecimal.ZERO : respLoanInfoQueryBean.getComIntRate().divide(new BigDecimal("100")));
            //应收利息累计 出单利息
            accLoanVO.setReceIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssueInt());
            //实收利息累计
            accLoanVO.setActualIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydInt());
            //欠息累计
            accLoanVO.setDelayIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblInt_1());
            // 正常贷款余额
            accLoanVO.setNormalBalance(Objects.isNull(respLoanBalanceQueryBean.getLoanBal()) ? BigDecimal.ZERO : respLoanBalanceQueryBean.getLoanBal());
            // 逾期起始日
            //accLoanVO.setCapOverdueDate("");
            // 当前逾期期数
            accLoanVO.setOverTimesCurrent(BigDecimal.ZERO);
            // 累计逾期期数
            accLoanVO.setOverTimesTotal(BigDecimal.ZERO);
            // 最高逾期期数
            accLoanVO.setMaxTimesTotal(BigDecimal.ZERO);
            // 客户经理
            accLoanVO.setCusManager(nlsCreditInfoVO.getNlsOperUserid());
            // 主管机构
            accLoanVO.setMainBrId(nlsCreditInfoVO.getNlsOperOrgid());
            // 结清日期
            accLoanVO.setSettlDate(respLoanInfoQueryBean.getCldDt());
            // 最后修改日期
            accLoanVO.setLastUpdateTime(TimeUtil.getCurrentDateTime());
            // 台账状态
            accLoanVO.setAccountStatus(LoanConstant.TZZT_ZC);
            // 利率类型 固定利率
            accLoanVO.setIntRateType(IR_MODE_FIXED);
            // 固定利率
            accLoanVO.setFixedRate(Objects.nonNull(respLoanInfoQueryBean.getComIntRate()) ? BigDecimal.ZERO : respLoanInfoQueryBean.getComIntRate().divide(new BigDecimal("100")));
            // 应收复利累计  贷款余额查询 已出单复利
            accLoanVO.setUnpdArrPrnBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssueCmpdInt());
            // 实收拖欠本金的罚息   贷款余额查询 已归还罚息
            accLoanVO.setActArrsIntBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydPnyInt());
            // 实收复利   贷款余额查询 已归还复利
            accLoanVO.setActArrPrnBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydCmpdInt());
            // 还款日   贷款信息查询 结息日respLoanInfoQueryBean.getIntSetlDt()
            accLoanVO.setReturnDate("21");
            // 拖欠本金 视台账状态插入
            accLoanVO.setUnpdPrinBal(BigDecimal.ZERO);
            // 支付方式
            accLoanVO.setPayWay(prodVo.getPayWay());
            // 拖欠本金的罚息（应收未收） 贷款余额查询 应还罚息
            accLoanVO.setUnpdArrsIntBal1(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblPnyInt_1());
            // 应收复利（应收未收）贷款余额查询 应还未还复利
            accLoanVO.setUnpdArrPrnBal1(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblCmpdInt_1());
            // 欠息累计  贷款余额查询 已出单罚息
            accLoanVO.setDelayIntCumu1(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssuePnyInt());
            // 产品类型 循环 非 循环
            accLoanVO.setPrdType("001");//循环额度
            // 主担保方式
            accLoanVO.setAssureMeansMain(nlsCreditInfoVO.getAssureMeansMain());
            // 还款方式  取支用申请信息表的还款方式
            accLoanVO.setRepaymentMode(nlsApplyInfoVo.getRepayMethod());
            // 创建人
            accLoanVO.setCreateUser(BaseConstant.ADMIN);
            // 创建时间
            accLoanVO.setCreateTime(TimeUtil.getCurrentDateTime());
            // 最后修改人
            accLoanVO.setLastUpdateUser(BaseConstant.ADMIN);
            // 身份证类型
            accLoanVO.setCertType(nlsApplyInfoVo.getCertType());
            // 身份证
            accLoanVO.setCertCode(nlsApplyInfoVo.getCertCode());
            // 授信协议号
            accLoanVO.setLmtContNo(lmtPrdContVo.getLmtContNo());
            // 贷款用途
            accLoanVO.setLoanUseType(nlsApplyInfoVo.getLoanPurpose());
            // 放款账号
            accLoanVO.setEnterAccount(nlsApplyInfoVo.getDnAccount());
            // 还款账号
            accLoanVO.setRepaymentAccount(nlsApplyInfoVo.getRecvAcctNo());
            // 渠道代码
            accLoanVO.setChannelCode(nlsApplyInfoVo.getChannelNo());
            // 当前期数 = 第一期
            accLoanVO.setCurrTerm(new BigDecimal(1));
            // 贷款期限
            accLoanVO.setLoanTerm(StringUtil.isNullorBank(nlsApplyInfoVo.getLoanTerm()) ? BigDecimal.ZERO : new BigDecimal(nlsApplyInfoVo.getLoanTerm()));
            // 期限类型
            accLoanVO.setLoadTermType(nlsApplyInfoVo.getLoanTermType());
            // 账务机构
            accLoanVO.setFinaBrId(Objects.nonNull(cusReferrerInfoVO)?cusReferrerInfoVO.getChargeOffBrId():"");
            // 宽限期
            accLoanVO.setGraceDay(new BigDecimal(Optional.ofNullable(respLoanInfoQueryBean.getGrcDay()).orElse("3")));
            // 账务日期
            accLoanVO.setBizDate(pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001));
            // 贷款种类
            accLoanVO.setLendType(nlsApplyInfoVo.getLendType());
            // 放款时间
            accLoanVO.setFirstDisbDate(pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001));
            int i = accLoanService.insertAccLoan(accLoanVO);
            AccLoanRespVO respVO = new AccLoanRespVO();
            respVO.setBillNo(accLoanVO.getBillNo());
            respVO.setAccountStatus(accLoanVO.getAccountStatus());
            respVO.setApplySeq(accLoanVO.getApplySeq());
            respVO.setCla(accLoanVO.getCla());
            respVO.setCreateTime(accLoanVO.getCreateTime());
            respVO.setDelayIntCumu(accLoanVO.getDelayIntCumu()==null?"0":accLoanVO.getDelayIntCumu().doubleValue()+"");
            respVO.setEnterAccount(accLoanVO.getEnterAccount());
            respVO.setLoanAmount(StringUtil.isNullorBank(respLoanInfoQueryBean.getContrOriglAmt()) ? "0" : new BigDecimal(respLoanInfoQueryBean.getContrOriglAmt()).doubleValue()+"");
            respVO.setNormalBalance(accLoanVO.getNormalBalance()==null?"0":accLoanVO.getNormalBalance().doubleValue()+"");
            respVO.setOverdueBalance(accLoanVO.getOverdueBalance()==null ?"0":accLoanVO.getOverdueBalance().doubleValue()+"");
            respVO.setOverdueDays(accLoanVO.getOverdueDays()==null?"0":accLoanVO.getOverdueDays().doubleValue()+"");
            respVO.setTableName("ACC_LOAN");
            sendToRisk(respVO,nlsApplyInfoVo.getApplySeq());
            if (i < 1) {
                msg = nlsApplyInfoVo.getApplySeq() + "借据数据落库异常";
                logger.error(msg);
                throw new RuntimeException(msg);
            }
        } catch (Exception e) {
            logger.error("放款成功后，同步借据信息，落表失败！", e);
            throw new OcmSystemException(SedNlsEnum.ExceptionLocation.LOAN_RELEASE_AFTER_INSERT_ACC_LOAN.getValue(), msg);
        }
    }

    /**
     * 开发人员：【chenxuan】
     * 创建/修改日期：【2019/5/24】
     * 修改描述：还款计划信息
     *
     * @return void
     * @Param [respRepaymentPlanListQueryBean]
     **/
    private void mutatorLoanRepayPlan(RespRepaymentPlanListQueryBean respRepaymentPlanListQueryBean, PrdInfoVO prodVo) throws Exception {
        List<LoanRepayPlanVO> loanRepayPlanVOS = loanRepayPlanService.qryAllByLoanNo(respRepaymentPlanListQueryBean.getAcctDtlInfArry().get(0).getAcctKwd());
        // 用信后如果已经插入则证明走的是补偿任务，无需再添加
        if (Objects.nonNull(loanRepayPlanVOS) && loanRepayPlanVOS.size() > 0)return;
        try {
            String endDt = respRepaymentPlanListQueryBean.getAcctDtlInfArry().get(0).getEndDt();
            String billno = respRepaymentPlanListQueryBean.getAcctDtlInfArry().get(0).getAcctKwd();
            //更新借据还款日，取还款计划表的应还款日字段
            AccLoanVO accLoanVO = new AccLoanVO();
            accLoanVO.setBillNo(billno);
            accLoanVO.setReturnDate(endDt.substring(endDt.length()-2,endDt.length()));
            accLoanService.updateByPk(accLoanVO);

            List<LoanRepayPlanVO> loanRepayPlanList = new ArrayList<LoanRepayPlanVO>(respRepaymentPlanListQueryBean.getAcctDtlInfArry().size());
            for (int i = 0; i < respRepaymentPlanListQueryBean.getAcctDtlInfArry().size(); i++) {
                LoanRepayPlanVO loanRepayPlan = new LoanRepayPlanVO();
                AcctDtlInfBean acctDtlInfBean = respRepaymentPlanListQueryBean.getAcctDtlInfArry().get(i);
                // 业务日期
                loanRepayPlan.setBizDate(pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001));
                // 产品ID
                loanRepayPlan.setProductCd(prodVo.getPrdId());
                // 款计划明细查询 账户主键
                loanRepayPlan.setRefNbr(acctDtlInfBean.getAcctKwd());
                // 还款期数  根据贷款发放查询“还款计划明细查询”的“期次”
                loanRepayPlan.setTerm(Integer.parseInt(acctDtlInfBean.getRpyTime()));
                // 开始日期   根据贷款发放查询“还款计划明细查询”的“起始日期”
                loanRepayPlan.setBeginDate(DateUtility.format8To10(acctDtlInfBean.getStartDt()));
                // 到期日期  根据贷款发放查询“还款计划明细查询”的“终止日期”
                loanRepayPlan.setStmtDate(DateUtility.format8To10(acctDtlInfBean.getEndDt()));
                // 期数状态 正常
                // status 期数状态 本期借款状态 NUMBER(17,2) Y N:正常 O:逾期 P:结清 F:非应计
                loanRepayPlan.setStatus(LoanConstant.REPAYPLAN_STATUE_N);
                //还款时插入 期供 caoxin:问尚聪 可能需要计算
                loanRepayPlan.setPerAmt(BigDecimal.ZERO);
                // 应还本金  根据贷款发放查询“还款计划明细查询”的“计划本金”
                loanRepayPlan.setPrincipal(new BigDecimal(acctDtlInfBean.getPlanPrin()));
                // 已还本金  根据贷款发放查询“还款计划明细查询”的“实还本金”
                loanRepayPlan.setPrincipalPaid(new BigDecimal(acctDtlInfBean.getActRpyPrin()));
                // 应还利息  根据贷款发放查询“还款计划明细查询”的“计划利息”
                loanRepayPlan.setInterest(new BigDecimal(acctDtlInfBean.getPlanInt()));
                // 已还利息 实还利息
                loanRepayPlan.setInterestPaid(new BigDecimal(acctDtlInfBean.getActRpyInt()));
                // 应还罚息  根据贷款发放查询“还款计划明细查询”的“出单罚息”
                loanRepayPlan.setPenaltyDue(new BigDecimal(acctDtlInfBean.getIssuePnyInt()));
                // 已还罚息  根据贷款发放查询“还款计划明细查询”的“实还罚息”
                loanRepayPlan.setPenaltyPaid(new BigDecimal(acctDtlInfBean.getActRpyPnyInt()));
                // 应还复利  根据贷款发放查询“还款计划明细查询”的“出单复利”
                loanRepayPlan.setComIntDue(new BigDecimal(acctDtlInfBean.getIssueCmpdInt()));
                // 已还复利  根据贷款发放查询“还款计划明细查询”的“实还复利”
                loanRepayPlan.setComIntPaid(new BigDecimal(acctDtlInfBean.getActRpyCmpdInt()));
                //应还费用
                loanRepayPlan.setFeeDue(BigDecimal.ZERO);
                //已还费用
                loanRepayPlan.setFeePaid(BigDecimal.ZERO);
                // 是否逾期 1是 0否
                String ISOVERDUE_NO = "0";
                loanRepayPlan.setIsOverDue(ISOVERDUE_NO);
                // 逾期标志
                loanRepayPlan.setOverdueFlag(ISOVERDUE_NO);
                // 宽限期这个值不为空 caoxin:需要debug表中无值
                try {
                    loanRepayPlan.setGraceDate(DateUtility.format8To10(acctDtlInfBean.getEndDt()));
                } catch (Exception e) {
                    loanRepayPlan.setGraceDate(acctDtlInfBean.getEndDt());
                }

                // 放完款后肯定没有逾期 逾期本金为0
                loanRepayPlan.setPrincipalDue(BigDecimal.ZERO);
                // 还款计划size
                loanRepayPlan.setInitTerm(respRepaymentPlanListQueryBean.getAcctDtlInfArry().size());
                loanRepayPlanList.add(loanRepayPlan);
                LoanRepayPlanRespVO respVO = new LoanRepayPlanRespVO();
                respVO.setBizDate(loanRepayPlan.getBizDate());
                respVO.setClearDate(loanRepayPlan.getClearDate());
                respVO.setInterest(loanRepayPlan.getInterest()==null?"0":loanRepayPlan.getInterest().doubleValue()+"");
                respVO.setOverdueFlag(loanRepayPlan.getOverdueFlag());
                respVO.setPrincipal(loanRepayPlan.getPrincipal()==null?"0":loanRepayPlan.getPrincipal().doubleValue()+"");
                respVO.setRefNbr(loanRepayPlan.getRefNbr());
                respVO.setStmtDate(loanRepayPlan.getStmtDate());
                respVO.setTableName("LOAN_REPAY_PLAN");
                respVO.setTerm(loanRepayPlan.getTerm()==null?"0":loanRepayPlan.getTerm().toString());
                sendToRisk(respVO,accLoanVO.getApplySeq());
            }

            int i = loanRepayPlanService.batchInsert(loanRepayPlanList);
            if (i < 1) {
                msg = "还款计划落库异常";
                logger.error("放款成功后，同步还款计划信息，落表失败！", msg);
                throw new RuntimeException(msg);
            }
        } catch (Exception e) {
            logger.error("放款成功后，同步还款计划信息，落表失败！", e);
            throw new OcmSystemException(SedNlsEnum.ExceptionLocation.LOAN_RELEASE_AFTER_INSERT_LOAN_PLAN.getValue(), msg);
        }
    }

    private void sendToRisk(Object obj,String applySeq) {
        logger.info("优e贷用信，发送kafka消息给大数据开始执行,流水号:" + applySeq);
        try {
            boolean flag = false;
            //查询开关
            List<NlsStageInfoVO> infoVOS = nlsStageInfoService.queryList();
            for(NlsStageInfoVO vo:infoVOS){
                if(vo.getPrdId().equals("11110004") && vo.getStatus().equals("on") && vo.getStage().equals("apply")){
                    flag = true;
                }
            }
            JSONObject jsonObject = new JSONObject();
            String timeStamp = TimeUtil.getTimeStampByPattern("yyyy-MM-dd HH:mm:ss");
            KafkaNoticeHeader header = new KafkaNoticeHeader();
            header.setMessageCode("YED_JISHI");
            header.setTimestamp(timeStamp);
            header.setTransactionId(getTransactionId());
            header.setSysName("netLoan");

            jsonObject.put("head", header);
            jsonObject.put("biz", obj);

            if(flag){
                threadPool.add(() -> {
                    KafkaUtil kafkaUtil = new KafkaUtil(kafkaServers, kafkaToptic);
                    try {
                        kafkaUtil.sendMessage(JSONObject.toJSONString(jsonObject));
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.error("优e贷用信，发送kafka消息给大数据失败，流水号：" + applySeq + ",异常信息：" + e.getMessage());
                    }
                });
            }
        } catch (Exception e) {
            logger.info("优e贷用信，发送kafka消息给大数据异常，流水号：" + applySeq + ",异常信息：" + e.getMessage());
        } finally {
            logger.info("优e贷用信，发送kafka消息给大数据结束，申请流水号：" + applySeq);
        }
    }

    public static String getTransactionId() {
        String transactionId = "SEQ" + DateFormatUtils.format(new Date(), DateFormatConstant.DATETIME_FORMAT_COMPACT, Locale.CHINA) +
                RandomCodeUtils.generateLetter(6);
        return transactionId;
    }


    /**
     * 开发人员：【chenxuan】
     * 创建/修改日期：【2019/6/3】
     * 修改描述：异常处理
     *
     * @return void
     * @Param [nlsProcessBizVo, e]
     **/
    private void setNlsProcessException(NlsProcessBizVO nlsProcessBizVo, Exception e) {
        logger.error(Arrays.toString(e.getStackTrace()));
        nlsProcessBizVo.setExceptionFlag(Boolean.TRUE);
        nlsProcessBizVo.setRefuseMsg(msg + e);
        nlsProcessBizVo.setExceptionMsg(e);
    }

    @Autowired
    @Qualifier("updateLmtPrdContService")
    private UpdateLmtPrdContService updateLmtPrdContService;

    @Autowired
    @Qualifier("pubSysInfoService")
    private PubSysInfoService pubSysInfoService;

    @Autowired
    @Qualifier("nlsApplyInfoService")
    private NlsApplyInfoService nlsApplyInfoService;
}
